﻿using System;
using System.Threading;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
using PhantomChainsAnalyser.Model;

namespace PhantomChainsAnalyser
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private ResultContainer Data = null;
        private MySqlConnection Connection = null;
        private Controller Calc = null;
        private MySqlDataReader DRQuery = null;
        private DataContainer Source = null;


        private void button1_Click(object sender, EventArgs e)
        {
            button1.Hide();
            groupBox4.Hide();
            groupBox6.Hide();
            dataGridView2.Rows.Clear();//очищаем таблицу
            dataGridView3.Rows.Clear();//очищаем таблицу
            try
            {
                Source = parse();
            }
            catch(Exception exp)
            {
                MessageBox.Show(exp.Message, "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                button1.Show();
                return;
            }
            Data = new ResultContainer();
            Calc = new Controller(Source, Data);
            Thread thread = new Thread(Calc.Calculate);
            thread.Start();
            timer2.Interval = 100;
            timer2.Start();
        }

        //подключение к БД и заполнение таблицы с исходными цепочками 
        private void timer1_Tick(object sender, EventArgs e)
        {
            MySqlConnectionStringBuilder config_string = new MySqlConnectionStringBuilder();
            config_string.UserID = "root";
            config_string.Database = "Complex_work";
            config_string.Server = "localhost";
            Connection = new MySqlConnection(config_string.ConnectionString);
            Connection.Open();
            string sql = "SELECT fl.file_file FROM files fl JOIN file_type fl_tp ON fl.file_type_id = fl.file_type_id JOIN sequence s ON s.file_id = fl.file_id JOIN object  o ON o.object_id = s.object_id JOIN object_type o_tp ON o.object_type_id = o_tp.object_type_id WHERE fl_tp.file_type_name = 'txt' AND o_tp.object_type_name = 'DNA'";
            MySqlCommand command = Connection.CreateCommand();
            command.CommandText = sql;
            DRQuery = command.ExecuteReader();
            int k = 0;
            while (DRQuery.Read())
            {
                string Temp = DRQuery.GetString(0);
                if (((Temp[1] == 'C') || (Temp[1] == 'T') || (Temp[1] == 'G') || (Temp[1] == 'A')) && ((Temp[0] == 'C') || (Temp[0] == 'T') || (Temp[0] == 'G') || (Temp[0] == 'A')))
                {
                    dataGridView1.Rows.Add();
                    dataGridView1.Rows[k].Cells[0].Value = k + 1;
                    dataGridView1.Rows[k].Cells[1].Value = Temp.Length;
                    dataGridView1.Rows[k].Cells[2].Value = Temp;
                    k++;
                }
                
            }
            Connection.Close();
            timer1.Stop();
        }

        private DataContainer parse()
        {
            DataContainer data = new DataContainer();
            int Number = Convert.ToInt32(textBox1.Text) - 1;
            if ((Number < 0) || (Number >= dataGridView1.RowCount))
            {
                throw new Exception("Недопустимый номер цепочки");
            }
            int Count = Convert.ToInt32(textBox2.Text);
            if (Count < 100)
            {
                throw new Exception("Слишком мало фантомных цепочек");
            }
            data.number = Number;
            data.count = Count;
            data.table = dataGridView1;
            data.DRQuery = DRQuery;
            data.Control1 = zedGraphControl1;
            data.Control2 = zedGraphControl2;
            data.Control3 = zedGraphControl3;
            return data;
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            lock (Data)
            {
                if (Data.Finished)
                {
                    button1.Show();
                    timer2.Stop();
                    if (Data.InvalidChain)
                    {
                        MessageBox.Show("Недопустимые значения во входной цепи", "Ошибка", MessageBoxButtons.OK,
                                        MessageBoxIcon.Stop);
                    }
                    else
                    {
                        for (int i = 0; i < Data.GeneratedChains.Count; i++)
                        {
                            dataGridView2.Rows.Add();
                            dataGridView3.Rows.Add();
                            dataGridView2.Rows[i].Cells[0].Value = i + 1;
                            dataGridView3.Rows[i].Cells[0].Value = i + 1;
                            lock(Data)
                            {
                                dataGridView2.Rows[i].Cells[1].Value = Data.GeneratedChains[i].ToString();
                                dataGridView3.Rows[i].Cells[1].Value = Data.Entropy[i];
                                dataGridView3.Rows[i].Cells[2].Value = Data.Regularity[i];
                                dataGridView3.Rows[i].Cells[3].Value = Data.AverageGeometricalInterval[i];
                            }
                        }
                        groupBox4.Show();
                        groupBox6.Show();
                        lock(Data)
                        {
                            label4.Text = "Среднее значение: " + Data.Entropy.AvеrageValue();
                            label5.Text = "Дисперсия: " + Data.Entropy.Dispersion().ToString("F9");
                            label6.Text = "СКО: " + Data.Entropy.MeanSquareDeviation().ToString("F9");
                            label9.Text = "Среднее значение: " + Data.Regularity.AvеrageValue();
                            label8.Text = "Дисперсия: " + Data.Regularity.Dispersion().ToString("F9");
                            label7.Text = "СКО: " + Data.Regularity.MeanSquareDeviation().ToString("F9");
                            label15.Text = "Среднее значение: " + Data.AverageGeometricalInterval.AvеrageValue();
                            label14.Text = "Дисперсия: " + Data.AverageGeometricalInterval.Dispersion().ToString("F9");
                            label13.Text = "СКО: " + Data.AverageGeometricalInterval.MeanSquareDeviation().ToString("F9");
                            label12.Text = "Энтропия: " + Data.InputChainEntropy;
                            label11.Text = "Регулярность: " + Data.InputChainRegularity;
                            label16.Text = "интервал: " + Data.InputChainAverageGeometricalInterval;
                        }
                    }
                    Data = null;
                    Source = null;
                }
            }
        }
    }
}